#ifndef WAKE_WORD_DETECT_H
#define WAKE_WORD_DETECT_H

#include <freertos/FreeRTOS.h>  // FreeRTOS核心头文件
#include <freertos/task.h>      // FreeRTOS任务管理
#include <freertos/event_groups.h>  // FreeRTOS事件组

#include <esp_afe_sr_models.h>  // ESP语音前端处理模型
#include <esp_nsn_models.h>     // ESP噪声抑制模型

#include <list>                 // 标准库链表容器
#include <string>               // 标准库字符串
#include <vector>               // 标准库向量容器
#include <functional>           // 标准库函数对象
#include <mutex>                // 标准库互斥锁
#include <condition_variable>   // 标准库条件变量

#include "audio_codec.h"        // 音频编解码器接口

/**
 * @brief 唤醒词检测类
 * 
 * 负责音频流中唤醒词的检测，支持多种唤醒词模型
 */
class WakeWordDetect {
public:
    /**
     * @brief 构造函数
     */
    WakeWordDetect();
    
    /**
     * @brief 析构函数
     */
    ~WakeWordDetect();

    /**
     * @brief 初始化唤醒词检测器
     * 
     * @param codec 音频编解码器指针
     */
    void Initialize(AudioCodec* codec);
    
    /**
     * @brief 输入音频数据进行唤醒词检测
     * 
     * @param data 待检测的音频数据
     */
    void Feed(const std::vector<int16_t>& data);
    
    /**
     * @brief 设置唤醒词检测回调函数
     * 
     * @param callback 检测到唤醒词时的回调函数
     */
    void OnWakeWordDetected(std::function<void(const std::string& wake_word)> callback);
    
    /**
     * @brief 启动唤醒词检测
     */
    void StartDetection();
    
    /**
     * @brief 停止唤醒词检测
     */
    void StopDetection();
    
    /**
     * @brief 检查唤醒词检测是否正在运行
     * 
     * @return 如果检测正在运行返回true，否则返回false
     */
    bool IsDetectionRunning();
    
    /**
     * @brief 获取每次Feed所需的数据大小
     * 
     * @return 每次Feed所需的采样点数
     */
    size_t GetFeedSize();
    
    /**
     * @brief 编码唤醒词音频数据
     * 
     * 将PCM格式的唤醒词音频编码为Opus格式
     */
    void EncodeWakeWordData();
    
    /**
     * @brief 获取Opus格式的唤醒词音频数据
     * 
     * @param opus 输出参数，用于存储Opus格式的音频数据
     * @return 如果有可用数据返回true，否则返回false
     */
    bool GetWakeWordOpus(std::vector<uint8_t>& opus);
    
    /**
     * @brief 获取最近检测到的唤醒词
     * 
     * @return 最近检测到的唤醒词字符串
     */
    const std::string& GetLastDetectedWakeWord() const { return last_detected_wake_word_; }

private:
    esp_afe_sr_iface_t* afe_iface_ = nullptr;  // ESP AFE接口
    esp_afe_sr_data_t* afe_data_ = nullptr;    // ESP AFE数据
    char* wakenet_model_ = NULL;               // 唤醒词模型名称
    std::vector<std::string> wake_words_;      // 支持的唤醒词列表
    EventGroupHandle_t event_group_;           // 事件组句柄，用于任务同步
    std::function<void(const std::string& wake_word)> wake_word_detected_callback_;  // 唤醒词检测回调
    AudioCodec* codec_ = nullptr;              // 音频编解码器指针
    std::string last_detected_wake_word_;      // 最近检测到的唤醒词

    TaskHandle_t wake_word_encode_task_ = nullptr;  // 唤醒词编码任务句柄
    StaticTask_t wake_word_encode_task_buffer_;     // 唤醒词编码任务静态缓冲区
    StackType_t* wake_word_encode_task_stack_ = nullptr;  // 唤醒词编码任务栈
    std::list<std::vector<int16_t>> wake_word_pcm_;  // PCM格式的唤醒词音频数据队列
    std::list<std::vector<uint8_t>> wake_word_opus_;  // Opus格式的唤醒词音频数据队列
    std::mutex wake_word_mutex_;               // 唤醒词数据互斥锁
    std::condition_variable wake_word_cv_;     // 唤醒词数据条件变量

    /**
     * @brief 存储唤醒词音频数据
     * 
     * @param data 音频数据指针
     * @param size 数据大小
     */
    void StoreWakeWordData(uint16_t* data, size_t size);
    
    /**
     * @brief 音频检测任务
     * 
     * 在单独的任务中运行唤醒词检测算法
     */
    void AudioDetectionTask();
};

#endif
